<?php
/**
 * TmallSpider.php class file.
 * @author wudg <544038230@qq.com>
 * @date 2020/10/26- 2:02 下午
 */

namespace common\drivers\spiderProduct;


use common\exception\CopyException;
use common\constants\PlatformConst;
use common\drivers\CookieDriver;
use common\drivers\interfaces\SpiderProductInterface;
use common\exception\DriverException;
use common\helpers\CookiesHelper;
use common\helpers\StringHelper;
use common\helpers\UrlsHelper;
use console\components\helpers\ConsoleHelper;
use QL\QueryList;
use yii\helpers\ArrayHelper;

class TmallSpider extends BaseSpider implements SpiderProductInterface
{

    /**
     * 万邦请求url 获取淘宝商品数据地址
     * @var string
     */
    protected $requestUrl = 'https://api-gw.onebound.cn/taobao/item_get/';
    /**
     * 失败重试3次
     * @var int
     */
    protected $tryTimes = 3;

    /**
     * 获取详细内容
     * @inheritDoc
     * @throws CopyException
     */
    public function getContents(string $url): string
    {
        $contentTimes = 0;
        while($contentTimes < $this->tryTimes)
        {
            $num_iid = UrlsHelper::getUrlPrimaryKey(PlatformConst::PLATFORM_TMALL, $url);
            $this->requestUrl .= '?key='.$this->key.'&&num_iid='.$num_iid.'&is_promotion=1&&lang=zh-CN&secret='.$this->secret;
            $resources = $this->spiderContent($this->requestUrl);

            $this->detailUrl = $url;
            if(!$resources)
            {
                throw new CopyException('获取数据源失败');
            }
            $contents = $resources->getBody()->getContents();
            if(!$contents)
            {
                $contentTimes++;
                ConsoleHelper::runInfo("抓取天猫商品失败，即将重试第{$contentTimes}次");
                continue;
            }
            //评率超限制，再次请求一次
            $formatContents = StringHelper::jsonDecode($contents);
            if($formatContents && isset($formatContents['error_code']) && $formatContents['error_code'] == '4008')
            {
                $contentTimes++;
                ConsoleHelper::runInfo("抓取天猫商品评率超限制，即将重试第{$contentTimes}次");
                continue;
            }
            $this->resources = $contents;
            break;
        }
        //数据没有获取到抛出异常
        if(!$this->resources)
        {
            throw new CopyException('获取数据源失败');
        }
        return $this->resources;
    }

    /**
     * 格式化数据
     * @inheritDoc
     * @throws DriverException
     */
    public function formatContents(): array
    {
        $this->resources = StringHelper::jsonDecode($this->resources);


        if(!isset($this->resources['item']) || empty($this->resources['item']))
        {
            throw new DriverException('数据源不存在或已下架');
        }
        /**
         * 标题和价格为空说明商品已经不存在了
         */
        if(empty($this->resources['item']['title']) || empty($this->resources['item']['price']))
        {
            throw new DriverException('数据源不存在');
        }

        $this->productInfo['platform'] = PlatformConst::PLATFORM_TB;

        $this->productInfo['mall_name'] = isset($this->resources['item']['seller_info']['shop_name']) && !empty($this->resources['item']['seller_info']['shop_name']) ?
            trim($this->resources['item']['seller_info']['shop_name']) : $this->resources['item']['nick'];

        $this->productInfo['mall_id'] = $this->resources['item']['shop_id'];

        $this->productInfo['title'] = $this->resources['item']['title'] ?? '';
        $this->productInfo['prices'] = $this->resources['item']['price'];

        $pics = ArrayHelper::getColumn($this->resources['item']['item_imgs'],'url');

        foreach($pics as $k => $pic)
        {
            if(!is_string($pic)) continue;
            $pics[$k] = $this->_imgUrl($pic);
        }
        $this->productInfo['pics'] = $pics;
        $this->productInfo['num_iid'] = $this->resources['item']['num_iid'];

        $this->productInfo['main_pic'] = is_string($this->resources['item']['pic_url']) ? $this->_imgUrl($this->resources['item']['pic_url']) : '';

        if(is_array($this->resources['item']['video']) &&  count($this->resources['item']['video']))
        {
            $this->productInfo['video'] = $this->resources['item']['video'];
        }

        if(isset($this->resources['item']['desc_img']) && is_array($this->resources['item']['desc_img']))
        {
            $this->productInfo['detail_gallery'] = $this->resources['item']['desc_img'];
        }

        if(is_array($this->resources['item']['props']) && count($this->resources['item']['props']))
        {
            $attr = [];
            foreach ($this->resources['item']['props'] as $k =>$item)
            {
                array_push($attr,['key'=>$item['name'],'value'=>$item['value']]);
            }
            $this->productInfo['attr'] = $attr;
        }
        $this->productInfo['cid'] = $this->resources['item']['cid'];


        $this->productInfo['pc_desc'] = $this->resources['item']['desc'] ?? '';

        $this->setSku();

        $this->setExtend();

        return $this->productInfo;
    }

    protected function setExtend()
    {
        $this->productInfo['extend_data'] = [
            'fav_count' => $this->resources['item']['fav_count'], //收藏量
            'total_sold' => $this->resources['item']['total_sold'], //评论数
            'sales' => $this->resources['item']['sales'], //销量
            'post_fee' => $this->resources['item']['post_fee'], //物流费用
            'express_fee' => $this->resources['item']['express_fee'], //快递费用
            'location' => $this->resources['item']['location'], //发货地
        ];
    }




    private function _imgUrl(string $imgPath)
    {
        $imgPath = str_replace(['https:','http:'],'',$imgPath);
        return 'https:'.$imgPath;
    }

    /**
     * set sku
     */
    protected function setSku()
    {
        $propsList = $propsImgList =[];
        if(isset($this->resources['item']['props_list']) && is_array($this->resources['item']['props_list']))
        {
            $propsList = $this->resources['item']['props_list'];
        }
        if(isset($this->resources['item']['props_img']) && is_array($this->resources['item']['props_img']))
        {
            $propsImgList = $this->resources['item']['props_img'];
        }
        /**
         * skuImg
         */
        if(count($propsImgList))
        {
            foreach ($propsImgList as $k => $propImg)
            {
                if(!isset($propsList[$k])) continue;
                $tmp = [];
                $listKeyList = explode(':',$propsList[$k]);
                $tmp['name'] = $listKeyList[0] ?? '';
                unset($listKeyList[0]);
                $tmp['value'] = implode(':',$listKeyList);
                $tmp['skuImg'] = is_string($propImg) ? $this->_imgUrl($propImg) : '';
                $tmp['key'] = $k;
                array_push($this->productInfo['sku_img'],$tmp);
            }
        }
        /**
         * sku
         */
        if(isset($this->resources['item']['skus']['sku']) && is_array($this->resources['item']['skus']['sku']))
        {
            foreach($this->resources['item']['skus']['sku'] as $k => $sku)
            {
                $tmp = [];
                $tmp['skuId'] = $sku['sku_id'];
                $tmp['stock'] = $sku['quantity'];
                $tmp['price'] = $sku['orginal_price']; //原价
                $tmp['sale_price'] = $sku['price']; //销售价
                $tmp['cover'] = '';

                $tmp['properties'] = StringHelper::jsonEncode(explode(';',$sku['properties']));
                $propertiesList = explode(';',$sku['properties']);
                $tmp['properties_name'] = [];
                foreach($propertiesList as $props)
                {
                    if(isset($propsImgList[$props]) && is_string($propsImgList[$props]))
                    {
                        $tmp['cover'] = $this->_imgUrl($propsImgList[$props]);
                    }
                    if(isset($propsList[$props]) && is_string($propsList[$props]))
                    {
                        array_push($tmp['properties_name'],$propsList[$props]);
                    }
                }
                $tmp['properties_name'] = StringHelper::jsonEncode($tmp['properties_name']);
                array_push($this->productInfo['skus'],$tmp);
            }
        }
    }

    /**
     * @inheritDoc
     */
    public function setErrorInfo(string $msg = '')
    {
        // TODO: Implement setErrorInfo() method.
    }

    /**
     * @inheritDoc
     */
    public function saveDb()
    {
        echo 'tmall - 入库' . PHP_EOL;
        // TODO: Implement saveDb() method.
    }

    /**
     * @inheritDoc
     */
    public function getErrorInfo()
    {
        return $this->errorInfo;
    }
}
